package com.kmust.dream.wanderingdream.order.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kmust.dream.wanderingdream.comm.pojo.ResultBean;
import com.kmust.dream.wanderingdream.order.config.DelayQueueConfig;
import com.kmust.dream.wanderingdream.order.dto.OrderStatus;
import com.kmust.dream.wanderingdream.order.entity.Order;
import com.kmust.dream.wanderingdream.order.entity.OrderPre;
import com.kmust.dream.wanderingdream.order.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Api("订单API")
@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    OrderService orderService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    /**
     * 获取所有的订单，包括能够已经被删除的或者未被删除的，该方法需要管理员权限
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有的订单，后台使用，前端不需要使用", notes = "无参数")
    @GetMapping("/getAllOrders")
    public ResultBean findAllOrders() {
        List<Order> list = orderService.list();
        return orderService.handler(list);
    }

    /**
     * 获取所有可见的订单
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有的能显示的订单，后台使用，前端不需要使用", notes = "无参数")
    @GetMapping("/getAllShowOrders")
    public ResultBean findAllShowOrders() {
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("order_show", 1);
        List<Order> list = orderService.list(orderQueryWrapper);
        return orderService.handler(list);
    }

    /**
     * 获取所有不可见订单，已经被删除的订单
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有的不能够显示的订单，后台使用，前端不需要使用", notes = "无参数")
    @GetMapping("/getAllNoShowOrders")
    public ResultBean findAllNoShowOrders() {
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("order_show", 0);
        List<Order> list = orderService.list(orderQueryWrapper);
        return orderService.handler(list);
    }

    /**
     * 用户获取所有自己的订单
     *
     * @param username 用户名
     * @return ResultBean
     */
    @ApiOperation(value = "通过用户名获取所有的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getAllOrdersByUsername/{username}")
    public ResultBean getAllOrdersByUsername(@PathVariable("username") String username) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<Order>().eq("username", username).eq("order_show", 1);
        List<Order> list = orderService.list(queryWrapper);
        return orderService.handler(list);
    }

    /**
     * 获取所有的订单，通过商品
     *
     * @param productId 商品id
     * @return ResultBean
     */
    @ApiOperation(value = "通过商品id主键获取所有的订单，后台使用，前端不需要使用", notes = "参数是productId")
    @GetMapping("/getAllOrdersByProductId/{productId}")
    public ResultBean getAllOrdersByProductId(@PathVariable("productId") Integer productId) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<Order>().eq("product_id", productId);
        List<Order> list = orderService.list(queryWrapper);
        return orderService.handler(list);
    }

    /**
     * 获取订单通过订单id
     *
     * @param orderId 订单id
     * @return ResultBean
     */
    @ApiOperation(value = "通过订单的id获取订单", notes = "参数是订单的id")
    @GetMapping("/getOrderByOrderId/{orderId}")
    @Cacheable(value = "order", key = "'order'+#orderId")
    public ResultBean getOrderByOrderId(@PathVariable("orderId") Integer orderId) {
        Order byId = orderService.getById(orderId);
        List<Order> list = new ArrayList<>();
        list.add(byId);
        return orderService.handler(list);
    }

    /**
     * 创建订单的方法，该方法还未完成，需要进行权限验证，具体是从redis中根据username拿出权限，判断权限。
     * 如果权限为空表示未登录，不允许进行创建订单。
     * 需要根据Feign接口调用sys的getUserInfo服务
     * （还未完成）
     *
     * @param orderPre 预处理类
     * @return ResultBean
     */
    @ApiOperation(value = "创建订单", notes = "无参数")
    @PostMapping("/createOrder")
    public ResultBean createOrder(@RequestBody OrderPre orderPre) {
        return orderService.createOrder(orderPre);
    }


    /**
     * 更新订单内容，根据orderId进行更新
     * 修改订单内容需要进行判断sku的库存(未完成)
     *
     * @param order 订单json
     * @return ResultBean
     */
    @ApiOperation(value = "修改订单内容", notes = "参数order的json字符串")
    @PutMapping("/updateOrder")
    @CacheEvict(value = "order", key = "'order'+#order.orderId")
    public ResultBean updateOrder(@RequestBody Order order) {
        return orderService.updateOrder(order);
    }


    /**
     * 假删除，把订单的order_show字段置为0，在查询的时候只查询该字段为1的数据
     *
     * @param orderId 订单主键
     * @return ResultBean
     */
    @ApiOperation(value = "删除订单（假删除）", notes = "参数是order的主键即orderId")
    @DeleteMapping("/deleteOrderByOrderId/{orderId}")
    @CacheEvict(value = "order", key = "'order'+#orderId")
    public ResultBean deleteOrderByOrderId(@PathVariable("orderId") Integer orderId) {
        return orderService.deleteOrderByOrderId(orderId);
    }


    /**
     * 更改每次的状态，
     * 0表示是未支付，
     * 1表示是已经支付但还未发货，
     * 2表示是已经发货但还未收货，
     * 3表示是确认收货(订单已完成)
     * 4表示该订单已经取消
     *
     * @param orderId 订单主键
     * @return ResultBean
     */
    @ApiOperation(value = "更改订单的状态", notes = "参数是order的主键即orderId，订单状态演变：未支付->未发货->运输中->已完成")
    @PutMapping("/updateOrderStatus/{orderId}")
    @CacheEvict(value = "order", key = "'order'+#orderId")
    public ResultBean updateOrderStatus(@PathVariable("orderId") Integer orderId) {
        return orderService.updateOrderStatus(orderId);
    }


    /**
     * 获取未支付的订单，即状态码是0
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有未支付订单，后台使用，前端不使用", notes = "无参数")
    @GetMapping("/getNonePayOrders")
    public ResultBean getNonePayOrders() {
        return orderService.getNonePayOrders();
    }

    /**
     * 查询用户的所有未支付订单
     *
     * @param username 用户名
     * @return ResultBean
     */
    @ApiOperation(value = "通过用户名获取所有未支付的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getNonePayOrdersByUsername/{username}")
    public ResultBean getNonePayOrdersByUsername(@PathVariable String username) {
        return orderService.getOrdersByStatus(username, OrderStatus.NONE_PAY);
    }

    /**
     * 获取未发货的订单，即状态码是1
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有未发货的订单，后台使用，前端不使用", notes = "无参数")
    @GetMapping("/getNoneSendOrders")
    public ResultBean getNoneSendOrders() {
        return orderService.getNoneSendOrders();
    }

    @ApiOperation(value = "通过用户名获取所有未发货的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getNoneSendOrdersByUsername/{username}")
    public ResultBean getNoneSendOrdersByUsername(@PathVariable String username) {
        return orderService.getOrdersByStatus(username, OrderStatus.NONE_SEND);
    }

    /**
     * 获取未收获的订单，即状态码是2
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有运输中（未收货）的订单，后台使用，前端不使用", notes = "无参数")
    @GetMapping("/getNoneReceiveOrders")
    public ResultBean getReceivePayOrders() {
        return orderService.getNoneReceiveOrders();
    }

    @ApiOperation(value = "通过用户名获取所有运输中（未收货）的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getNoneReceiveOrdersByUsername/{username}")
    public ResultBean getNoneReceiveOrdersByUsername(@PathVariable String username) {
        return orderService.getOrdersByStatus(username, OrderStatus.NONE_RECEIVE);
    }

    /**
     * 获取已完成的订单，即状态码是3
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有已经完成的订单，后台使用，前端不使用", notes = "无参数")
    @GetMapping("/getAlreadyOrders")
    public ResultBean getAlreadyOrders() {
        return orderService.getAlreadyOrders();
    }

    @ApiOperation(value = "通过用户名获取所有已经完成的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getAlreadyOrdersByUsername/{username}")
    public ResultBean getAlreadyOrdersByUsername(@PathVariable String username) {
        return orderService.getOrdersByStatus(username, OrderStatus.HAVE_ALREADY);
    }


    /**
     * 获取所有的取消订单
     *
     * @return ResultBean
     */
    @ApiOperation(value = "获取所有已经取消的订单，后台使用，前端不使用", notes = "无参数")
    @GetMapping("/getCancelOrders")
    public ResultBean getCancelPayOrders() {
        return orderService.getCancelOrders();
    }

    @ApiOperation(value = "通过用户名获取所有已经取消的订单", notes = "参数是用户名即用户的主键")
    @GetMapping("/getCancelOrdersByUsername/{username}")
    public ResultBean getCancelOrdersByUsername(@PathVariable String username) {
        return orderService.getOrdersByStatus(username, OrderStatus.HAVE_CANCEL);
    }

    /**
     * 取消订单，在支付不能完成或者主动取消的情况下，将订单的状态改变。(未完成)
     *
     * @param orderId 订单id
     * @return ResultBean
     */
    @ApiOperation(value = "取消订单", notes = "参数是orderId")
    @DeleteMapping("/cancelOrder/{orderId}")
    @CacheEvict(value = "order", key = "'order'+#orderId")
    public ResultBean cancelOrder(@PathVariable Integer orderId) {

        return orderService.cancelOrder(orderId);
    }


    /**
     * 通过订单id和倒计时设置支付倒计时
     *
     * @param orderId   订单id
     * @param delayTime 延时时间 单位是ms 1000进率
     */
    @ApiOperation(value = "内部测试接口，不需要关注", notes = "orderId，delayTime延迟时间的单位是ms")
    @GetMapping("/payCount/{orderID}/{delayTime}")
    public void sendDelayMsg(@PathVariable("orderID") Integer orderId, @PathVariable("delayTime") Integer delayTime) {
        String message = String.valueOf(orderId);
        log.info("当前时间：{}，发送一条时长是{}的信息{}给ttl队列QC", new Date(), delayTime, message);
        rabbitTemplate.convertAndSend(DelayQueueConfig.DELAYED_EXCHANGE_NAME, DelayQueueConfig.DELAYED_ROUTING_KEY, message, msg -> {
            msg.getMessageProperties().setDelay(delayTime);
            return msg;
        });
    }

    @ApiOperation(value = "修改订单支付成功状态")
    @PutMapping("/changePayStatus/{orderId}")
    public ResultBean changePayStatus(@PathVariable Integer orderId) {
        return orderService.changePayStatus(orderId);
    }

}
